package com.example.group.network.express_plus_app.ui.login;

import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.MutableLiveData;

import android.app.Application;
import android.util.Log;
import android.util.Patterns;
import android.widget.Toast;

import com.android.volley.AuthFailureError;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.example.group.network.express_plus_app.MainApplication;
import com.example.group.network.express_plus_app.bean.Token;
import com.example.group.network.express_plus_app.bean.User;
import com.example.group.network.express_plus_app.data.LoginDataSource;
import com.example.group.network.express_plus_app.data.LoginRepository;
import com.example.group.network.express_plus_app.data.Result;
import com.example.group.network.express_plus_app.data.model.LoggedInUser;
import com.example.group.network.express_plus_app.R;
import com.example.group.network.express_plus_app.http.GsonRequest;
import com.example.group.network.express_plus_app.http.MySingleton;

import java.util.HashMap;
import java.util.Map;

public class LoginViewModel extends AndroidViewModel implements LoginDataSource.ResponseListener {

    private MutableLiveData<LoginFormState> loginFormState = new MutableLiveData<>();
    private MutableLiveData<LoginResult> loginResult = new MutableLiveData<>();

    private final LoginRepository loginRepository;
    Application application;


    String server_ip;

    RequestQueue queue;
    String request_token_url;
    String request_user_url;
    private Token token;
    public LoginViewModel(@NonNull Application application) {
        super(application);
        this.application=application;
        LoginDataSource loginDataSource = new LoginDataSource();
        this.loginRepository = LoginRepository.getInstance(loginDataSource,application);
        loginDataSource.setResponseListener(this);

        server_ip=application.getString(R.string.server_ip);
        request_token_url=server_ip+"express-auth2/oauth/token?";
        request_user_url=server_ip+"express-user/user-controller/find-user-info-by-phone?";
        //初始化queue
        queue= MySingleton.getInstance(application).
                getRequestQueue();
    }

    public MutableLiveData<LoginResult> getLoginResult() {
        return loginResult;
    }

    public MutableLiveData<LoginFormState> getLoginFormState() {
        return loginFormState;
    }


    //这里并没有返回值，所以设返回值也没用，主类通过观察LoginResult的变化来确定是否成功
    public void login(String username, String password) {
        // can be launched in a separate asynchronous job
        //loginRepository.login(username, password);//回调的方法里不能设置liveData
        requestToken(username,password);
    }
    //退出登录
    public void logout() {
        // can be launched in a separate asynchronous job
        loginRepository.logout();
        //loginResult.setValue(new LoginResult(null,true));
        Toast.makeText(application, "退出成功！", Toast.LENGTH_SHORT).show();
    }




    public void loginDataChanged(String username, String password) {
        if (!isUserNameValid(username)) {
            loginFormState.setValue(new LoginFormState(R.string.invalid_username, null));
        } else if (!isPasswordValid(password)) {
            loginFormState.setValue(new LoginFormState(null, R.string.invalid_password));
        } else {
            loginFormState.setValue(new LoginFormState(true));
        }
    }

    // A placeholder username validation check
    private boolean isUserNameValid(String username) {
        if (username == null) {
            return false;
        }
        if (username.contains("@")) {
            return Patterns.EMAIL_ADDRESS.matcher(username).matches();
        } else {
            return !username.trim().isEmpty();
        }
    }
    // A placeholder password validation check
    private boolean isPasswordValid(String password) {
        return password != null && password.trim().length() > 5;
    }




    public void setResultSuccess(Result.Success<LoggedInUser> result) {
        Log.i("登陆回调","登录回调成功");
        LoggedInUser user = result.getData();
        LoginResult loginResult2 = new LoginResult(new LoggedInUserView(user.getPhone(), user.getDisplayName()));
        Log.i("loginResult",loginResult2.getSuccess().getPhone());
        loginResult.setValue(loginResult2);

        MainApplication mainApplication=MainApplication.getInstance();
        mainApplication.mInfoMap.put("phone",user.getPhone());
        mainApplication.mInfoMap.put("token",user.getAccessToken());
        mainApplication.mInfoMap.put("user_face",user.getImagePath());
        mainApplication.mInfoMap.put("net_name",user.getDisplayName());
        mainApplication.mInfoMap.put("delivery_address",user.getDeliveryAddress());
        //保存user到数据库
        loginRepository.setLoggedInUser(user);

    }

    @Override
    public void setResultError(Result.Error error) {
        loginResult.setValue(new LoginResult(error.toString()));
    }

    //回调使用
    private OkListener okListener; //定义一个用户信息监听器
    public void setResponseListener(OkListener listener){
        okListener=listener;
    }

    public interface OkListener{
        void setLoginOk(boolean user);
    }



    public void requestToken(String phone, String password )  {
        Log.i("token","开始请求token");
        GsonRequest<Token> tokenGsonRequest=new GsonRequest<Token>(request_token_url, Request.Method.POST, Token.class, null, new Response.Listener<Token>() {
            @Override
            public void onResponse(Token response) {
                Log.i("token", response.getAccess_token());
                //调用请求用户信息的方法
                requestUser(response.getAccess_token(),phone);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.i("LoginDataSource", error.toString());
            }
        }){
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String,String> parms=new HashMap<>();
                parms.put("grant_type","password");
                parms.put("client_id","c1");
                parms.put("client_secret","123456");
                parms.put("username",phone);
                parms.put("password",password);
                return parms;
            }
        };
        tokenGsonRequest.setRetryPolicy(new DefaultRetryPolicy(6000,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        queue.add(tokenGsonRequest);

    }

    //请求用户信息
    public void requestUser(String token,String phone){
        Map<String,String> head=new HashMap<>();
        head.put("Authorization","Bearer "+token);
        GsonRequest<User> userGsonRequest=new GsonRequest<User>(request_user_url, Request.Method.POST, User.class, head, new Response.Listener<User>() {
            @Override
            public void onResponse(User response) {
                //调用请求用户信息的方法
                //将token保存到共享参数
                Log.i("user",response.toString());

                Log.i("登陆回调","登录回调成功");
                LoggedInUser user=new LoggedInUser(response.getUserPhone(),response.getUserNetName(),
                        token,response.getUserFace(),response.getUserDeliveryAddress().getDeliveryAddress());
                loginResult.setValue(new LoginResult(new LoggedInUserView(user.getPhone(),user.getDisplayName())));

                MainApplication mainApplication=MainApplication.getInstance();
                mainApplication.mInfoMap.put("phone",user.getPhone());
                mainApplication.mInfoMap.put("token",user.getAccessToken());
                mainApplication.mInfoMap.put("user_face",user.getImagePath());
                mainApplication.mInfoMap.put("net_name",user.getDisplayName());
                mainApplication.mInfoMap.put("delivery_address",user.getDeliveryAddress());
                //保存user到数据库
                loginRepository.setLoggedInUser(user);

                //信息回调
/*                LoggedInUser loggedInUser=new LoggedInUser(response.getUserPhone(),response.getUserNetName(),
                        token,response.getUserFace(),response.getUserDeliveryAddress().getDeliveryAddress());
                Result.Success<LoggedInUser> loggedInUserSuccess = new Result.Success<>(loggedInUser);
                responseListener.setResultSuccess(loggedInUserSuccess);*/
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.i("LoginDataSource", "用户信息请求错误"+error.toString());
                Result.Error error1 = new Result.Error(error);
                //responseListener.setResultError(error1);
            }
        }){
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String,String> parms=new HashMap<>();
                parms.put("userPhone",phone);
                return parms;
            }
        };
        userGsonRequest.setRetryPolicy(new DefaultRetryPolicy(6000,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        queue.add(userGsonRequest);
    }

}